#include "JS300XUart.h"
#include "MCUConfig.h"
#include "MCUPhaser.h"
#include "MCUUart.h"

#if 0
TYPE_BUF_UART uart_buf;
bool uart_dma_perr = false;
u16 dma_rcv_len = 0;
u16 dma_rcv_len_backup = 0;
u8 UartState = UART_STATE_GETREADYDATA;

#define PROTO_LEN 10

u16 uart_get_rxbuf_datalen(void)
{
    s16 len = 0;
    len = uart_buf.rx_index_put - uart_buf.rx_index_get;
    if (len < 0)
    {
        len += UART_RBUF_LEN;
    }
    return (u16)len;
}

u16 uart_get_txbuf_datalen(void)
{
    s16 len = 0;
    len = uart_buf.tx_index_put - uart_buf.tx_index_get;
    if (len < 0)
    {
        len += UART_TBUF_LEN;
    }
    return (u16)len;
}

u16 uart_get_txbuf_freespace(void)
{
    s16 len = 0;
    len = uart_buf.tx_index_put - uart_buf.tx_index_get;
    if (len < 0)
    {
        len += UART_TBUF_LEN;
    }
    len = UART_TBUF_LEN - 1 - len;
    return (u16)len;
}

u16 uart_get_rxbuf_data(u8 *desbuf, u16 len)
{
    u16 i = 0;
    u16 rxlen = 0;
    rxlen = uart_get_rxbuf_datalen();
    if (desbuf)
    {
        len = (len < rxlen) ? len : rxlen;
        for (i = 0; i < len; i++)
        {
            desbuf[i] = uart_buf.rx_buf[uart_buf.rx_index_get++];
            uart_buf.rx_index_get = (uart_buf.rx_index_get) % (UART_RBUF_LEN);
        }
        return len;
    }
    return 0;
}

u16 uart_put_txbuf_data(uint8_t *srcbuf, uint16_t len)
{
    u16 i = 0;
    u16 writelength = 0;
    if (NULL == srcbuf)
    {
        return 0;
    }
    writelength = uart_get_txbuf_freespace();
    writelength = (writelength >= len) ? len : writelength;
    if (0 != writelength)
    {
        for (i = 0; i < writelength; i++)
        {
            uart_buf.tx_buf[uart_buf.tx_index_put++] = srcbuf[i];
            uart_buf.tx_index_put = (uart_buf.tx_index_put) % (UART_TBUF_LEN);
        }
        return writelength;
    }
    return 0;
}

void JS300XUartInit()
{
    uart_buf.rx_index_get = 0;
    uart_buf.rx_index_put = 0;
    dma_rcv_len = 0;
    dma_rcv_len_backup = 0;
    UartState = UART_STATE_GETREADYDATA;

    TYPE_LL_GPIO_INIT gpio_struct;
    NVIC_InitTypeDef nvic;
    /* UART configuration structure variable             */
    TYPE_LL_UART_INIT uart_cfg;
    TYPE_LL_UART_DMA_CFG uart_dma_cfg;
    memset(&gpio_struct, 0x00, sizeof(gpio_struct));
    /* Initialize the relevant variables of the UART     */
    //    / uart_buf_init();
    memset(&uart_buf, 0x0, sizeof(uart_buf));
    memset(&uart_cfg, 0x0, sizeof(uart_cfg));
    memset(&uart_dma_cfg, 0x00, sizeof(uart_dma_cfg));

    /* pc1 func0   rx   fpga:h21 pc0 func0   tx   fpga:f22 */
    gpio_struct.gpio_pin = LL_GPIO_PIN_6;
    gpio_struct.gpio_mode = LL_GPIO_MODE_AF;
    gpio_struct.gpio_pupd  = LL_GPIO_PUPD_UP;
    ll_gpio_init(GPIOC, &gpio_struct);
    ll_gpio_pin_af_config(GPIOC, LL_GPIO_PIN_SOURCE_6, LL_GPIO_AF_0);
    gpio_struct.gpio_pin = LL_GPIO_PIN_7;
    ll_gpio_init(GPIOC, &gpio_struct);
    ll_gpio_pin_af_config(GPIOC, LL_GPIO_PIN_SOURCE_7, LL_GPIO_AF_0);

    /* Configure information about the UART             */
    /* Configure UART baud rate to UART_BAUDRATE        */
    // uart_cfg.baudrate = LL_UARTx_BAUDRATE_9600;
    uart_cfg.baudrate = LL_UARTx_BAUDRATE_9600;
    uart_cfg.bit_width_sel = LL_UART_WORD_LENGTH_8B;
    uart_cfg.parity = LL_UART_PARITY_NO;
    uart_cfg.stop_bit_sel = LL_UART_STOP_1B;
    uart_cfg.work_mode = LL_UART_WORK_MODE_FULL_DUPLEX;
    /* Call the UART driver configuration function      */
    ll_uart_init(UART1, &uart_cfg);
    ll_uart_enable(UART1);

    /*  uart1 dma init */
    uart_dma_cfg.dma_tx_ie = ENABLE;
    uart_dma_cfg.dma_rx_ie = ENABLE;
    uart_dma_cfg.dma_tx_en = DISABLE;
    uart_dma_cfg.dma_rx_en = ENABLE;
    uart_dma_cfg.dma_tx_addr = (u32)uart_buf.tx_buf;
    uart_dma_cfg.dma_rx_addr = (u32)uart_buf.rx_buf;
    uart_dma_cfg.dma_want_tx_len = 0;
    /* dma want rx len  = (UART_RBUF_LEN - 1) for rx_index_get and rx_index_put % UART_RBUF_LEN calculate */
    // rom always not enough so fuck you
    //   #define UART_RBUF_LEN 128
    uart_dma_cfg.dma_want_rx_len = UART_RBUF_LEN - 1;
    uart_dma_cfg.dma_rx_perr_ie = ENABLE;
    ll_uart_dma_config(UART1, &uart_dma_cfg);

    /* Configure UART baud rate to UART_BAUDRATE        */
    uart_cfg.parity = LL_UART_PARITY_NO;
    /* Call the UART driver configuration function */
    // ll_uart_init(UART0, &uart_cfg);
    // ll_uart_enable(UART0);
    // debug_select_interface_set(DEBUG_UART0);
    nvic.NVIC_IRQChannel = UART1_IRQn;
    nvic.NVIC_IRQChannelPriority = 0;
    nvic.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic);
    delay_ms(1);

    ll_uart1_dma_rx_disable();
    ll_uart1_dma_rx_enable();
}

#if 0
//0 need recive still
//1 recive over
int JS300XUartRecv()
{
    int Res = 0;
    dma_rcv_len = ll_uart_dma_rx_len_get(UART1);

    if (((dma_rcv_len_backup != dma_rcv_len)) && ((false == uart_buf.rx_begin)))
    {
        dma_rcv_len_backup = dma_rcv_len;
        uart_buf.rx_cur_systick = GetSysTick();
        uart_buf.rx_begin = true;
        //说明一直在检测

    }

    //5ms time out
    if ((true == uart_buf.rx_begin) && (is_systick_expired(uart_buf.rx_cur_systick, 5))) /* 35ms rx timeout */
    {
        RxTimeOutCtrl(2);
        dma_rcv_len = ll_uart_dma_rx_len_get(UART1);
        if (dma_rcv_len_backup == dma_rcv_len)
        {
            ll_uart1_dma_rx_disable();
            if (false == uart_dma_perr)
            {
                //u16 tx_spacelen = 0;
                u16 rx_get_real_len = 0;
                uart_buf.rx_index_get = 0;
                uart_buf.rx_index_put = dma_rcv_len % UART_RBUF_LEN;
                u8 tmp_buf[UART_TBUF_LEN] = {0};
                //  tx_spacelen  = uart_get_txbuf_freespace();
                rx_get_real_len = uart_get_rxbuf_data(tmp_buf, UART_TBUF_LEN);
                memcpy(RxBuffer, tmp_buf, rx_get_real_len);
                Phaser();
                ResetRxIndex();
                Res = 1;
            }
            else
            {
                uart_dma_perr = false;
            }
            uart_buf.rx_index_get = 0;
            uart_buf.rx_index_put = 0;
            ll_uart1_dma_rx_enable();
            dma_rcv_len = 0;
            dma_rcv_len_backup = 0;
            uart_buf.rx_begin = false;
        }
        else
        {
            dma_rcv_len_backup = dma_rcv_len;
            uart_buf.rx_cur_systick = GetSysTick();
        }
    }
    else if (RxTimeOutCtrl(1))
    {
        ResetRxIndex();
        Res = 1;
    }
    return Res;
}

#else

extern u16 PinState;
extern bool isUartRecvTimeOut;
extern short CntUartTimeOut;
extern u8 Version;
u8 EndIdx = 0;
// #define LOOSE_UART 10000
#define UART_TIMEOUT 10000
// 5ms is one pin
// bool isEnableDma = false;

int JS300XUartRecv()
{
#if 1
    // CntUartTimeOut是记录时间的，靠这个来判断帧
    dma_rcv_len = ll_uart_dma_rx_len_get(UART1);
    if (dma_rcv_len_backup != dma_rcv_len){
        dma_rcv_len_backup = dma_rcv_len;
        CntUartTimeOut = UART_TIMEOUT;
        isUartRecvTimeOut = false;
    }
    if (false == isUartRecvTimeOut){
        if ((CntUartTimeOut < 1)){
            isUartRecvTimeOut = true;
            ll_uart1_dma_rx_disable();
            dma_rcv_len = 0;
            dma_rcv_len_backup = 0;
            ll_uart1_dma_rx_enable();
        }
        //和以前方式不同， 10ms没收到数据，判断一帧结束，会清空数据
        else if ((CntUartTimeOut < (UART_TIMEOUT - 10)) && (dma_rcv_len > 0)){
            if ((0x55 == uart_buf.rx_buf[0]) && (0x6 == uart_buf.rx_buf[1]))
            {
                u16 Sum = 0;
                for (int i = 2; i < 8; i++)
                {
                    Sum += uart_buf.rx_buf[i];
                }
                u8 Crc = (1 + (~Sum) & 0xFF);
                // 校验ok
                if (Crc == uart_buf.rx_buf[8])
                {
                    Version = uart_buf.rx_buf[2];
                    NTC1 = (uart_buf.rx_buf[1 + 2] << 8) | uart_buf.rx_buf[2 + 2];
                    NTC2 = (uart_buf.rx_buf[3 + 2] << 8) | uart_buf.rx_buf[4 + 2];
                    PinState &= ~(S2PROTO_PIN_ZERO1 | S2PROTO_PIN_ZERO2);
                    if (0 != ((1 << 2) & uart_buf.rx_buf[5 + 2]))
                    {
                        PinState |= S2PROTO_PIN_ZERO2;
                    }

                    if (0 != ((1 << 1) & uart_buf.rx_buf[5 + 2]))
                    {
                        PinState |= S2PROTO_PIN_ZERO1;
                    }
										///isUartRecvTimeOut = true;
                }
                // 清除缓存，防止解析成上次的数据
                uart_buf.rx_buf[0] = 0x0;
            }
            // 源码并不好，还得考虑到0 == dma_rcv_len,判断的状态实在太多了
            ll_uart1_dma_rx_disable();
            dma_rcv_len = 0;
            dma_rcv_len_backup = 0;
            ll_uart1_dma_rx_enable();
        }
    }
    return 0;
#else
    if (CntUartTimeOut < 1){
        uart_buf.rx_begin = false;
        // 尝试恢复数据
        CntUartTimeOut = 1000;
        isUartRecvTimeOut = true;
    }
    if (false == uart_buf.rx_begin){
        dma_rcv_len = 0;
        dma_rcv_len_backup = 0;
        ll_uart1_dma_rx_enable();
        uart_buf.rx_begin = true;
    }
    else{
        dma_rcv_len = ll_uart_dma_rx_len_get(UART1);
        if (dma_rcv_len_backup != dma_rcv_len){
            dma_rcv_len_backup = dma_rcv_len;
            if (dma_rcv_len < (UART_RBUF_LEN - PROTO_LEN) && (dma_rcv_len > 3)){
                if (0x55 == uart_buf.rx_buf[dma_rcv_len - 3] &&
                    0x6 == uart_buf.rx_buf[dma_rcv_len - 2]){
                    EndIdx = dma_rcv_len + 6;
                }
            }
            else if (dma_rcv_len >= (UART_RBUF_LEN - PROTO_LEN)){
                // 接收超出缓冲区就报异常
                uart_buf.rx_begin = false;
                EndIdx = 0;
            }
            if ((EndIdx > 0) && (dma_rcv_len >= EndIdx))            {
                // 接收长度ok
                ll_uart1_dma_rx_disable();
                uart_buf.rx_begin = false;
                EndIdx = dma_rcv_len - 7;
                u16 Sum = 0;
                u8 Crc = 0;
                for (; EndIdx < (dma_rcv_len - 1); EndIdx++){
                    Sum += uart_buf.rx_buf[EndIdx];
                }
                Crc = (1 + (~Sum) & 0xFF);
                EndIdx = dma_rcv_len - 7;
                if (Crc == uart_buf.rx_buf[dma_rcv_len - 1]){
                    CntUartTimeOut = 10000;
                    isUartRecvTimeOut = false;
                    Version = uart_buf.rx_buf[EndIdx];
                    NTC1 = (uart_buf.rx_buf[1 + EndIdx] << 8) | uart_buf.rx_buf[2 + EndIdx];
                    NTC2 = (uart_buf.rx_buf[3 + EndIdx] << 8) | uart_buf.rx_buf[4 + EndIdx];
                    PinState &= ~(S2PROTO_PIN_ZERO1 | S2PROTO_PIN_ZERO2);
                    if (0 != ((1 << 2) & uart_buf.rx_buf[5 + EndIdx])){
                        PinState |= S2PROTO_PIN_ZERO2;
                    }
                    if (0 != ((1 << 1) & uart_buf.rx_buf[5 + EndIdx])){
                        PinState |= S2PROTO_PIN_ZERO1;
                    }
                }
                EndIdx = 0;
            }
        }
    }
    return 0;
#endif
}

#endif

// 0 ok can be recv
// 1 to get data
// 2 to send

int JS300XUartSend()
{
    int Res = UART_STATE_SEND;
    if (false == uart_buf.tx_begin)
    {
        if ((u16)1 > uart_get_txbuf_datalen())
        {
            // 将要发送的数据给到缓存里
            //  UARTSnd(cmd);
            uart_put_txbuf_data((uint8_t *)TxBuffer, 9);
        }
        else
        {
            ll_uart_dma_want_tx_len_set(UART1, uart_get_txbuf_datalen());
            ll_uart1_dma_tx_enable();
            uart_buf.tx_begin = true;
            Res = UART_STATE_RECV;

#if 0
            // RxTimeOutCtrl(2);
            //发送数据
            uart_buf.rx_index_get = 0;
            uart_buf.rx_index_put = 0;
            ll_uart1_dma_rx_enable();
            dma_rcv_len = 0;
            dma_rcv_len_backup = 0;
            uart_buf.rx_begin = false;
#endif
            RxTimeOut = RX_TIMEOUT;
        }
    }
    return Res;
}

void JS300XUARTSnd(Cmd cmd)
{
    uart_put_txbuf_data((uint8_t *)TxBuffer, strlen(TxBuffer));
}

#else

#define UART_BUF_LEN      20

u8 tx_buf[UART_BUF_LEN] = {0};
u8 rx_buf[UART_BUF_LEN] = {0};
u8 tx_index = 0;
u8 rx_index = 0;
u8 pre_tx_len = 0;
bool rx_finish = false;

void uart_init(){
    __enable_irq();
    ll_wdt_stop(WDT);

    ll_gpio_config(PB, PIN_10 | PIN_11, LL_GPIO_MD_AF_PP);
    ll_gpio_af_sel(PB, PIN_10 | PIN_11, LL_GPIO_AF_0);
    
    ll_uart_config(UART1, 9600, LL_UART_PARITY_NO);
    
    ll_uart_tx_complete_interrupt_enable(UART0);        //使能发送完成中断
    ll_uart_rx_buf_not_empty_interrupt_enable(UART0); //使能接收缓冲不为空中断
    ll_uart_rx_timeout_interrupt_enable(UART0);         //使能接收超时中断
    ll_uart_rx_timeout_enable(UART0);                   //接收超时检测使能
    ll_uart_enable(UART0);
    
    NVIC_EnableIRQ(UART0_IRQn);
}

extern u8 Version;
extern u16 PinState;
u8 rx_tmp[PROTO_LEN];
void uart_parse(void)
{
    if ((0x55 == rx_tmp[0]) && (0x6 == rx_tmp[1])) {
      u16 Sum = 0;
      for (int i = 2; i < 8; i++) {
        Sum += rx_tmp[i];
      }
      u8 Crc = (1 + (~Sum) & 0xFF);
      // 校验ok
      if (Crc == rx_tmp[8]) {
        Version = rx_tmp[2];
        NTC1 = (rx_tmp[1 + 2] << 8) | rx_tmp[2 + 2];
        NTC2 = (rx_tmp[3 + 2] << 8) | rx_tmp[4 + 2];
        PinState &= ~(S2PROTO_PIN_ZERO1 | S2PROTO_PIN_ZERO2);
        if (0 != ((1 << 2) & rx_tmp[5 + 2])) {
          PinState |= S2PROTO_PIN_ZERO2;
        }

        if (0 != ((1 << 1) & rx_tmp[5 + 2])) {
          PinState |= S2PROTO_PIN_ZERO1;
        }
        /// isUartRecvTimeOut = true;
      }
      // 清除缓存，防止解析成上次的数据
      rx_tmp[0] = 0x0;
    }
}

void uart_rx_irq_handle(void)
{
    volatile u16 rx_data = 0;
    volatile u8 loop = 0;
    volatile u8 rx_cnt = 0;
    volatile u8 rx_parity_err = 0;
    
    if(LL_UART_RX_BUF_NOT_EMPTY_PENDING_GET(UART0))    //获取接收缓冲区是否为空pending
    {
        rx_cnt = LL_UART_RX_CNT_GET(UART0);            //获取接收数据的数量
        for(loop = 0;loop < rx_cnt;loop++)
        {   
            /* parity err bit map, bit 1 is parity err */
            rx_parity_err = LL_UART_RX_PERR_PENDING_GET(UART0);//奇偶校验标志位
            if(true == ll_uart_rx(UART0,(u16 *)&rx_data))
            {
                if(0 == ((rx_parity_err >> 0) & 0x01))
                {
                    rx_buf[rx_index++] = rx_data;
                    rx_index %= UART_BUF_LEN;
                }
            }
        }
        LL_UART_RX_BUF_NOT_EMPTY_PENDING_CLR(UART0);  //清除接收缓冲区为空pending
    }
    if(LL_UART_RX_TIMEOUT_PENDING_GET(UART0))         //获取接收超时pending
    {
        //rx_finish = true;
        //pre_tx_len = rx_index;
        if(PROTO_LEN == rx_index){
            memcpy(rx_tmp, rx_buf, PROTO_LEN);
            uart_parse();
        }
        rx_index = 0;
        LL_UART_RX_TIMEOUT_PENDING_CLR(UART0);        //清除接收超时pending
    }
}


//if not send?
short get_tx_buf_len(void){
    return (pre_tx_len-tx_index); 
}

void set_tx_buf_len(u8 *buf, short len){
    // memcpy(tx_buf, buf, len);
    pre_tx_len = len;
    tx_index = 0;
    ll_uart_irq_tx(UART0,tx_buf[tx_index++]);
}

//some thing error,
volatile char cnt_tx_time_out = 9;
void uart_tx_irq_handle(void)
{
    if(LL_UART_TX_COMPLETE_PENDING_GET(UART0))//获取发送完成pending
    {
        if(tx_index < pre_tx_len)
        {
            ll_uart_irq_tx(UART0, tx_buf[tx_index++]);
            cnt_tx_time_out = 39;
        }
        LL_UART_TX_COMPLETE_PENDING_CLR(UART0);//清除发送完成pending
    }
}

#endif
